<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="Content-Language" content="zh-CN"><title>systemd.offline-updates
  中文手册 [金步国]</title><style>
@font-face { font-family: "JinBuGuoWebMono"; src: url("http://www.jinbuguo.com/d/mono.ttf") format("truetype"); }
* { font-family: "JinBuGuoWebMono", "Ubuntu Mono", "Consolas", "Menlo", monospace; }
body { margin:10px; }
h1 { text-align:center; background:#ddd; }
h2#auth_name { text-align:center; margin: 10px 5%; }

    a.headerlink {
      color: #c60f0f;
      font-size: 0.8em;
      padding: 0 4px 0 4px;
      text-decoration: none;
      visibility: hidden;
    }

    a.headerlink:hover {
      background-color: #c60f0f;
      color: white;
    }

    h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, dt:hover > a.headerlink {
      visibility: visible;
    }
</style><script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><h1>systemd.offline-updates 中文手册</h1><h2 id="auth_name">译者：<strong><a href="http://www.jinbuguo.com/">金步国</a></strong></h2><hr><h3>版权声明</h3><p>本文译者是一位开源理念的坚定支持者，所以本文虽然不是软件，但是遵照开源的精神发布。</p><ul><li>无担保：本文译者不保证译文内容准确无误，亦不承担任何由于使用此文档所导致的损失。</li><li>自由使用：任何人都可以自由的<u>阅读/链接/打印</u>此文档，无需任何附加条件。</li><li>名誉权：任何人都可以自由的<u>转载/引用/再创作</u>此文档，但必须保留译者署名并注明出处。</li></ul><h3>其他作品</h3><p>本文译者十分愿意与他人分享劳动成果，如果你对我的其他翻译作品或者技术文章有兴趣，可以在如下位置查看现有的作品集：</p><ul><li><a href="http://www.jinbuguo.com/">金步国作品集</a> [ <a href="http://www.jinbuguo.com/">http://www.jinbuguo.com/</a> ]</li></ul><h3>联系方式</h3><p>由于译者水平有限，因此不能保证译文内容准确无误。如果你发现了译文中的错误(哪怕是错别字也好)，请来信指出，任何提高译文质量的建议我都将虚心接纳。</p><ul><li>Email(QQ)：70171448在QQ邮箱</li></ul><hr><a href="systemd.index.html">手册索引</a> ·
  <a href="systemd.directives.html">指令索引</a><span style="float:right">systemd-241</span><hr><div class="refentry"><a name="systemd.offline-updates"></a><div class="titlepage"></div><div class="refnamediv"><h2>名称</h2><p>systemd.offline-updates — systemd 离线系统更新机制</p></div><div class="refsect1"><a name="id-1.4"></a><h2 id="离线系统更新机制">离线系统更新机制<a class="headerlink" title="Permalink to this headline" href="systemd.offline-updates.html#%E7%A6%BB%E7%BA%BF%E7%B3%BB%E7%BB%9F%E6%9B%B4%E6%96%B0%E6%9C%BA%E5%88%B6">¶</a></h2><p>本手册页描述了如何实现 systemd 风格的"离线"系统更新。
    所谓"离线"系统更新，是指将系统启动到一个特殊的"系统更新模式"，
    并在此模式下执行软件包的安装与更新操作，
    从而避免直接更新正在使用的例如动态库或可执行程序之类的文件(因为这种操作可能造成系统故障)。本文档遵循
    <a class="ulink" href="https://wiki.gnome.org/Design/OS/SoftwareUpdates" target="_top">GNOME design whiteboard</a> 规范。
    </p><p>逻辑步骤如下：</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>软件包管理程序下载好系统更新所需要的全部更新包(RPM 或 DEB 之类)，
        并将其存放在例如
        <code class="filename">/var/lib/system-update</code>
        这样的目录里(也可能是软件包管理程序特定用来存放更新包的其他目录)</p></li><li class="listitem"><p>当用户确认要执行离线系统更新之后，将会创建 <code class="filename">/system-update</code> 软连接，
        并将其指向 <code class="filename">/var/lib/system-update</code>
        目录(也可能是软件包管理程序特定用来存放更新包的其他目录)，然后重新启动操作系统。
        之所以将软连接直接创建在根目录下，是因为在系统启动的早期就要检测它的存在，
        而此时 <code class="filename">/var</code> 有可能尚未挂载。</p></li><li class="listitem"><p>在重新启动之后很早期的阶段，如果
        <a href="systemd-system-update-generator.html#"><span class="citerefentry"><span class="refentrytitle">systemd-system-update-generator</span>(8)</span></a>
        检测到存在 <code class="filename">/system-update</code> 软连接，那么它将会仅为本次启动将
        <code class="filename">default.target</code> 软连接临时指向
        <code class="filename">system-update.target</code> 目标。该目标单元中仅包含启动基本系统所必须的
         <code class="filename">sysinit.target</code> 目标(仅挂载所有文件系统而不启动任何其他服务)，
        以及用于执行系统更新操作的更新服务。</p></li><li class="listitem"><p>系统继续向着 <code class="filename">default.target</code> 目标(也就是包含了所有系统更新服务的
         <code class="filename">system-update.target</code> 目标)启动。
        每一个系统更新都应该仅实际执行一个特定的更新服务(参见下一步)，
        所有其他更新服务都应该不执行任何操作，只需干净的退出并返回"成功"状态码即可。
        所有更新服务都必须安排在 <code class="filename">sysinit.target</code> 之后执行，
        这样可以确保在执行更新操作的时候，所有文件系统都已经挂载完毕。</p></li><li class="listitem"><p>每一个更新服务启动之后的第一步都应该是立即检查
        <code class="filename">/system-update</code> 软连接是否指向了该更新服务所要求的正确位置。
        如果指向了错误位置或者软连接根本不存在，那么该更新服务必须什么也不做，立即退出并返回"成功"状态码。
        虽然可以同时安装多个更新服务，也可以同时并行启动多个更新服务，
        但是仅有那个在重启之前<span class="emphasis"><em>创建</em></span>了软连接的工具所对应的更新服务，
        才可以实际执行系统更新操作，所有其他更新服务必须什么也不做。
        因为同时执行多个系统更新的操作是不安全的，也就是多个系统更新必须以串行的方式一个接一个的执行。</p></li><li class="listitem"><p>如果 <code class="filename">/system-update</code> 软连接确实指向了正确的位置，
        那么更新服务将会首先尝试创建一个文件系统快照(如果确实可以的话)，然后安装全部更新包。
        无论更新操作是否成功，接下来必须使用例如 <span class="command"><strong>systemctl reboot</strong></span> 之类的命令重新启动。
        如果更新失败并且之前曾经成功的创建了文件系统快照，
        那么更新脚本应该按照先前创建的快照回滚文件系统(不含 <code class="filename">/system-update</code> 软连接)。</p></li><li class="listitem"><p>更新脚本应该仅在更新完成之后才能退出。
        执行实际更新操作的更新服务应该在完成更新操作之后重启系统。
        如果最终成功到达了 <code class="filename">system-update.target</code> 目标，
        也就是已经运行了所有更新服务，并且 <code class="filename">/system-update</code> 软连接依然存在，
        那么软连接将会被删除，并且整个系统将会被视为以大功告成的安全方式重启。</p></li><li class="listitem"><p>重启之后，因为已经不再存在 <code class="filename">/system-update</code> 软连接了，
        所以 <code class="filename">default.target</code> 也就不会再被临时重定向。
        整个系统将以正常模式向默认目标启动。</p></li></ol></div></div><div class="refsect1"><a name="id-1.5"></a><h2 id="建议">建议<a class="headerlink" title="Permalink to this headline" href="systemd.offline-updates.html#%E5%BB%BA%E8%AE%AE">¶</a></h2><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>为了提高可靠性，建议软件包直接向
        <code class="filename">system-update.target</code> 的 <code class="filename">.wants/</code>
        目录添加软连接来调用更新脚本，而不是在预安装阶段使用 <span class="command"><strong>systemctl
        enable</strong></span> 命令。进一步明确的说，
        就是要为软件包的更新脚本创建一个不含 [Install] 小节的 foobar.service 文件，然后添加一个类似
        <code class="filename">/usr/lib/systemd/system-update.target.wants/foobar.service</code>
        → <code class="filename">../foobar.service</code> 这样的软连接。</p></li><li class="listitem"><p>确保尽可能早的在更新脚本中删除 <code class="filename">/system-update</code> 软连接，
         以避免在更新失败时导致循环重启。</p></li><li class="listitem"><p>在更新服务的单元文件中为更新脚本使用 <code class="varname">FailureAction=reboot</code> ，
        以确保在更新失败后触发自动重启。
        <code class="varname">FailureAction=</code> 仅用于在更新脚本非正常退出时(退出码非零或被中断或崩溃)，
        确保可以触发特定的动作或启动特定的单元。
        如果更新脚本成功的完成了所有操作，那么应该自己触发重启动作，例如可以调用 logind 的
        <span class="command"><strong>Reboot()</strong></span> 函数，或者使用 <span class="command"><strong>systemctl reboot</strong></span> 命令。详见
        <a class="ulink" href="https://www.freedesktop.org/wiki/Software/systemd/logind" target="_top">logind dbus API</a>
        手册。</p></li><li class="listitem"><p>更新服务应该明确声明 <code class="varname">DefaultDependencies=no</code>,
        <code class="varname">Requires=sysinit.target</code>, <code class="varname">After=sysinit.target</code>,
        <code class="varname">After=system-update-pre.target</code> ，
        同时应该明确将所依赖的其他服务包含在依赖关系中。</p></li><li class="listitem"><p>当启动到离线更新模式时，
        如果需要运行辅助单元(该单元本身不安装更新)，
        那么可以创建一个包含
        <code class="varname">Wants=system-update-pre.target</code> 与
        <code class="varname">Before=system-update-pre.target</code>
        的 .service 单元，并在
        <code class="filename">/usr/lib/systemd/system-update.target.wants/</code>
        目录中添加一个指向该单元的软连接。</p></li></ol></div></div><div class="refsect1"><a name="id-1.6"></a><h2 id="参见">参见<a class="headerlink" title="Permalink to this headline" href="systemd.offline-updates.html#%E5%8F%82%E8%A7%81">¶</a></h2><p>
      <a href="systemd.html#"><span class="citerefentry"><span class="refentrytitle">systemd</span>(1)</span></a>,
      <a href="systemd.generator.html#"><span class="citerefentry"><span class="refentrytitle">systemd.generator</span>(7)</span></a>,
      <a href="systemd-system-update-generator.html#"><span class="citerefentry"><span class="refentrytitle">systemd-system-update-generator</span>(8)</span></a>,
      <a href="https://www.mankier.com/8/dnf.plugin.system-upgrade"><span class="citerefentry"><span class="refentrytitle">dnf.plugin.system-upgrade</span>(8)</span></a>
    </p></div></div></body></html>
